package com.taysear.parcel.fieldfactory;

import java.util.List;

import javax.persistence.Query;

import com.taysear.parcel.ParcelApplication;
import com.taysear.parcel.domain.Bus;
import com.taysear.parcel.domain.Employee;
import com.taysear.parcel.domain.Route;
import com.taysear.parcel.domain.RouteDetail;
import com.taysear.parcel.domain.Substation;
import com.taysear.parcel.util.Constants;
import com.vaadin.addon.jpacontainer.JPAContainer;
import com.vaadin.addon.jpacontainer.JPAContainerFactory;
import com.vaadin.addon.jpacontainer.fieldfactory.FieldFactory;
import com.vaadin.addon.jpacontainer.fieldfactory.SingleSelectTranslator;
import com.vaadin.data.Item;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.BeanContainer;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.data.util.filter.And;
import com.vaadin.data.util.filter.Compare.Equal;
import com.vaadin.data.util.filter.Not;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.Field;

public class LoadingsheetFieldFactory extends FieldFactory {
	private static final long serialVersionUID = -7356310781257588283L;

	public final ComboBox route = new ComboBox("Route");
	public final ComboBox origin = new ComboBox("Origin");
	public final ComboBox destination = new ComboBox("Destination");
	public final ComboBox bus = new ComboBox("Bus");
	public final ComboBox driver = new ComboBox("Driver");
	public final ComboBox conductor = new ComboBox("Conductor");

	public LoadingsheetFieldFactory(final ParcelApplication app) {
		List<Route> values = app.em.createQuery("SELECT rd.route FROM RouteDetail rd Where rd.route.routeStatus.id = 1 AND rd.substation.substationId = " + app.getUser().getEmployee().getSubstation().getSubstationId()).getResultList();

		BeanContainer<Integer, Route> routesContainer = new BeanContainer<Integer, Route>(Route.class);
		routesContainer.setBeanIdProperty("id");
		
		for (Route r : values) {
			routesContainer.addBean(r);
			route.setItemCaption(r.getId(), r.getRouteStart().getName() + " - " + r.getRouteEnd().getName());
		}
		
		route.focus();
		route.setWidth(Constants.COMMON_FIELD_WIDTH);
		route.setImmediate(true);
		//route.setPropertyDataSource(new SingleSelectTranslator(route));
		route.setContainerDataSource(routesContainer);
		route.setNullSelectionAllowed(false);
		route.setFilteringMode(ComboBox.FILTERINGMODE_STARTSWITH);
		route.setRequired(true);
		route.addListener(new ValueChangeListener() {
			@Override
			public void valueChange(ValueChangeEvent event) {
				if(event.getProperty().getValue() != null) {
					JPAContainer<Substation> sender_station = JPAContainerFactory.make(Substation.class, app.PERSISTENCE_UNIT);
					sender_station.addContainerFilter(new Equal("substationId",app.getUser().getEmployee().getSubstation().getSubstationId()));
					//origin.setPropertyDataSource(new SingleSelectTranslator(origin));
					origin.setContainerDataSource(sender_station);
					origin.setValue(sender_station.getItemIds().iterator().next());
	
					List<Substation> destinationSubstations = app.em.createQuery("SELECT rd.substation FROM RouteDetail rd Where rd.substation.station.status.id = 1 AND rd.substation.status.id = 1 AND rd.substation.substationId != " + app.getUser().getEmployee().getSubstation().getSubstationId() + " AND rd.route.id = " + route.getValue()).getResultList();
	
					BeanContainer<Integer, Substation> destinationContainer = new BeanContainer<Integer, Substation>(Substation.class);
					destinationContainer.setBeanIdProperty("substationId");
					
					for (Substation s : destinationSubstations) {
						destinationContainer.addBean(s);
						destination.setItemCaption(s.getSubstationId(), s.getName());
					}
					//destination.setPropertyDataSource(new SingleSelectTranslator(destination));
					destination.setContainerDataSource(destinationContainer);
				}	
			}
		});
		
		origin.setWidth(Constants.COMMON_FIELD_WIDTH);
		origin.setNullSelectionAllowed(false);
		origin.setItemCaptionPropertyId("name");
		origin.setFilteringMode(ComboBox.FILTERINGMODE_STARTSWITH);
		origin.setRequired(true);

		destination.setWidth(Constants.COMMON_FIELD_WIDTH);
		destination.setNullSelectionAllowed(false);
		destination.setFilteringMode(ComboBox.FILTERINGMODE_STARTSWITH);
		destination.setRequired(true);

		JPAContainer<Bus> buses = JPAContainerFactory.make(Bus.class, app.PERSISTENCE_UNIT);
		bus.setWidth(Constants.COMMON_FIELD_WIDTH);
		//bus.setPropertyDataSource(new SingleSelectTranslator(bus));
		bus.setContainerDataSource(buses);
		bus.setItemCaptionPropertyId("registrationNumber");
		bus.setNullSelectionAllowed(false);
		bus.setFilteringMode(ComboBox.FILTERINGMODE_STARTSWITH);
		bus.setRequired(true);

		JPAContainer<Employee> drivers = JPAContainerFactory.make(Employee.class, app.PERSISTENCE_UNIT);
		Equal empType1 = new Equal("employeeType.employeeTypeId",1);
		Equal empStatus = new Equal("employeeStatus.employeeStatusId", 1);
		drivers.addContainerFilter(new And(empType1, empStatus));
		
		driver.setWidth(Constants.COMMON_FIELD_WIDTH);
		//driver.setPropertyDataSource(new SingleSelectTranslator(driver));
		driver.setContainerDataSource(drivers);
		driver.setItemCaptionMode(ComboBox.ITEM_CAPTION_MODE_ITEM);
		driver.setNullSelectionAllowed(false);
		driver.setFilteringMode(ComboBox.FILTERINGMODE_STARTSWITH);
		driver.setRequired(true);
		
		JPAContainer<Employee> conductors = JPAContainerFactory.make(Employee.class, app.PERSISTENCE_UNIT);
		Equal empType2 = new Equal("employeeType.employeeTypeId", 2);
		conductors.addContainerFilter(new And(empType2, empStatus));
		
		conductor.setWidth(Constants.COMMON_FIELD_WIDTH);
		//conductor.setPropertyDataSource(new SingleSelectTranslator(conductor));
		conductor.setContainerDataSource(conductors);
		conductor.setItemCaptionMode(ComboBox.ITEM_CAPTION_MODE_ITEM);
		conductor.setNullSelectionAllowed(false);
		conductor.setFilteringMode(ComboBox.FILTERINGMODE_STARTSWITH);
		conductor.setRequired(true);
	}

	@Override
	public Field createField(Item item, Object propertyId, Component uiContext) {
		Field f;
		if ("route".equals(propertyId)) {
			return route;
		}
		if ("origin".equals(propertyId)) {
			return origin;
		}
		if ("destination".equals(propertyId)) {
			destination.setRequiredError("Please select a destination");
			return destination;
		}
		if ("bus".equals(propertyId)) {
			bus.setRequiredError("Please select a bus");
			return bus;
		}
		if ("driver".equals(propertyId)) {
			driver.setRequiredError("Please select a driver");
			return driver;
		}
		if ("conductor".equals(propertyId)) {
			conductor.setRequiredError("Please select a conductor");
			return conductor;
		} else {
			// Use the super class to create a suitable field base on the
			// property type.
			f = super.createField(item, propertyId, uiContext);
		}
		return f;
	}
}
